package com.example.security.service;

import com.example.core.constant.Constant;
import com.example.security.session.SysUserSession;
import com.example.core.utils.*;
import com.example.sys.org.po.SysUser;
import com.example.sys.org.service.SysUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Service
public class SysTokenServiceImpl implements SysTokenService {

    @Resource
    private RedisTemplate<String, SysUserSession> redisTemplate;

    @Value("${token.max}")
    private int maxTime;

    private SysUserService sysUserService;

    public SysUserService getSysUserService() {
        if (sysUserService == null) {
            sysUserService = (SysUserService) SpringBeanUtils.getBean(SysUserService.class);
        }
        return sysUserService;
    }

    @Override
    public boolean verify(ServletRequest request, ServletResponse response) {
        boolean flag = true;
        String tokenKey = ((HttpServletRequest) request).getHeader(Constant.TOKEN);
        if (StringUtils.isEmpty(tokenKey)) {
            flag = false;
        } else {
            flag = verifyToken(tokenKey) && refreshToken(tokenKey);
        }
        return flag;
    }


    /***
     * 创建token并返回token key
     * @param userId
     * @return
     */
    @Override
    public String createToken(String userId) {
        String tokenKey = IdGenerator.generateUUIDId();
        SysUserSession sysUserSession = new SysUserSession(userId, IPUtils.getIpAddress(), DateTimeUtils.getTimeAddSecond(maxTime).getTime());
        redisTemplate.opsForValue().set(tokenKey, sysUserSession, maxTime, TimeUnit.SECONDS);
        return tokenKey;
    }


    @Override
    public boolean removeToken() {
        String tokenKey = getTokenKey();
        if (StringUtils.isNotEmpty(tokenKey)) {
            return redisTemplate.delete(tokenKey);
        }
        return false;
    }

    @Override
    public String getTokenKey() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null && servletRequestAttributes.getRequest() != null) {
            return servletRequestAttributes.getRequest().getHeader(Constant.TOKEN);
        }
        return null;
    }

    @Override
    public boolean verifyToken(String tokenKey) {
        if (StringUtils.isNotEmpty(tokenKey) && redisTemplate.hasKey(tokenKey)) {
            SysUserSession sysUserSession = (SysUserSession) redisTemplate.opsForValue().get(tokenKey);
            if (sysUserSession != null) {
                return sysUserSession.getExpireTime() > DateTimeUtils.getNow().getTime();
            }
        }
        return false;
    }

    @Override
    public boolean verifyToken() {
        boolean flag = false;
        String tokenKey = getTokenKey();
        if (StringUtils.isNotEmpty(tokenKey)) {
            flag = redisTemplate.hasKey(tokenKey);
        }
        return flag;
    }

    @Override
    public boolean refreshToken(String tokenKey) {
        SysUserSession sysUserSession = redisTemplate.opsForValue().get(tokenKey);
        return refreshToken(sysUserSession.getUserId(), tokenKey);
    }

    @Override
    public boolean refreshToken(String userId, String tokenKey) {
        SysUserSession sysUserSession = new SysUserSession(userId, IPUtils.getIpAddress(), DateTimeUtils.getTimeAddSecond(maxTime).getTime());
        redisTemplate.opsForValue().set(tokenKey, sysUserSession, maxTime, TimeUnit.SECONDS);
        return true;
    }


    /***
     * 获取当前登录用户
     * @param tokenKey
     * @return
     */
    @Override
    public SysUser getUser(String tokenKey) {
        SysUserSession sysUserSession = redisTemplate.opsForValue().get(tokenKey);
        return getSysUserService().getById(sysUserSession.getUserId());
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @Override
    public SysUser getUser() {
        String tokenKey = getTokenKey();
        if (StringUtils.isEmpty(tokenKey)){
            return null;
        }
        SysUserSession sysUserSession = redisTemplate.opsForValue().get(tokenKey);
        return getSysUserService().getById(sysUserSession.getUserId());
    }
}
